package com.ang.future;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

/**
 * @author ssang
 * @date 2023-02-22 22:59
 */
@Component
public class FutureTest02 {
    @Autowired
    private ExecutorService executorService1;

    public void test1(){
        FileReader fr1 = null;
        BufferedReader br1 = null;
        FileReader fr2 = null;
        BufferedReader br2 = null;
        FileWriter fw = null;
        BufferedWriter bw = null;
        try{
            //开始时间
            long startTime = System.currentTimeMillis();
            //关键字IP的集合
            List<String> ipList = new ArrayList<>();
            fr1 = new FileReader("D:\\test\\test.txt");
            br1 = new BufferedReader(fr1);
            String line = null;
            while((line = br1.readLine()) != null){
                System.out.println(line);
                ipList.add(line);
            }

            //日志的集合
            List<String> contentList = new ArrayList<>();
            fr2 = new FileReader("D:\\test\\2023022201.log");
            br2 = new BufferedReader(fr2);
            String content = null;
            while((content = br2.readLine()) != null){
                contentList.add(content);
            }

            //构造map
            long s3 = System.currentTimeMillis();
            Map<String, List<String>> logMap = new HashMap<>();
            for(String ip : ipList){
                List<String> ipContentList = new ArrayList<>();
                for (String c : contentList) {
                    if(c.contains(ip)){
                        ipContentList.add(c);
                    }
                }
                logMap.put(ip, ipContentList);
            }
            long e3 = System.currentTimeMillis();
            System.out.println("构造map耗时：" + (e3 - s3));

            System.out.println(logMap.keySet().size());


            fw = new FileWriter("D:\\test\\result.log");
            bw = new BufferedWriter(fw);

            //遍历写入文本
            for(String ip : logMap.keySet()){
                List<String> list = logMap.get(ip);

                //第一条记录的时间
                int s1 = (ip + " - - [").length();
                int e1 = list.get(0).indexOf("]");
                String content1 = list.get(0).substring(s1,e1);

                //最后一条记录的时间
                int s2 = (ip + " - - [").length();
                int e2 = list.get(list.size()-1).indexOf("]");
                String content2 = list.get(list.size()-1).substring(s2,e2);

                String result = ip +"-------------->"+ content1 +" - "+ content2;

                try {
                    bw.write(result);
                    bw.newLine();
                    //flush，或者close之后，才能将缓存写入文件
                    bw.flush();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                System.out.println(result);
            }

            //结束时间
            long endTime = System.currentTimeMillis();
            System.out.println("耗时：" + (endTime - startTime));

        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if(bw!=null){

            }
            if(fw!=null){

            }
            if(br1!=null){

            }
            if(fr2!=null){

            }
            if(br2!=null){

            }
            if(fr1!=null){

            }
        }
    }

    public void test2(){
        FileReader fr1 = null;
        BufferedReader br1 = null;
        FileReader fr2 = null;
        BufferedReader br2 = null;
        FileWriter fw = null;
        BufferedWriter bw = null;

        List<Future<Map<String,List<String>>>> futureList = new ArrayList<>();

        try{
            //开始时间
            long startTime = System.currentTimeMillis();

            //关键字IP的集合
            long s1 = System.currentTimeMillis();
            List<String> ipList = new ArrayList<>();
            fr1 = new FileReader("D:\\test\\test.txt");
            br1 = new BufferedReader(fr1);
            String line = null;
            while((line = br1.readLine()) != null){
                System.out.println(line);
                ipList.add(line);
            }
            long e1 = System.currentTimeMillis();
            System.out.println("读取txt耗时：" + (e1 - s1));

            //日志的集合
            long s2 = System.currentTimeMillis();
            List<String> contentList = new ArrayList<>();
            fr2 = new FileReader("D:\\test\\2023022201.log");
            br2 = new BufferedReader(fr2);
            String content = null;
            while((content = br2.readLine()) != null){
                contentList.add(content);
            }
            long e2 = System.currentTimeMillis();
            System.out.println("读取log耗时：" + (e2 - s2));

            //构造map
            long s3 = System.currentTimeMillis();
            Map<String, List<String>> logMap = new HashMap<>();
            for(String ip : ipList){
                Future<Map<String,List<String>>> future = executorService1.submit(this.handleMapCallable(ip, contentList));
                futureList.add(future);
            }
            for (Future<Map<String, List<String>>> future : futureList) {
                Map<String,List<String>> futureMap = future.get();
                futureMap.forEach((k,v)->{
                    logMap.merge(k,v,(k1,k2)->k2);
                });
            }
            long e3 = System.currentTimeMillis();
            System.out.println("构造map耗时：" + (e3 - s3));
            System.out.println(logMap.keySet().size());

            //遍历写入文本
            fw = new FileWriter("D:\\test\\result.log");
            bw = new BufferedWriter(fw);
            long s4 = System.currentTimeMillis();
            for(String ip : logMap.keySet()){
                List<String> list = logMap.get(ip);

                int sc1 = (ip + " - - [").length();
                int ec1 = list.get(0).indexOf("]");
                String content1 = list.get(0).substring(sc1,ec1);

                //最后一条记录的时间
                int sc2 = (ip + " - - [").length();
                int ec2 = list.get(list.size()-1).indexOf("]");
                String content2 = list.get(list.size()-1).substring(sc2,ec2);

                String result = ip +"-------------->"+ content1 +" - "+ content2;

                if(result!=null){
                    bw.write(result);
                    bw.newLine();
                    bw.flush();
                }
            }
            long e4 = System.currentTimeMillis();
            System.out.println("写入result耗时：" + (e4 - s4));

            //结束时间
            long endTime = System.currentTimeMillis();
            System.out.println("总共耗时：" + (endTime - startTime));

        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if(bw!=null){

            }
            if(fw!=null){

            }
            if(br1!=null){

            }
            if(fr2!=null){

            }
            if(br2!=null){

            }
            if(fr1!=null){

            }
        }
    }

    //处理返回值的callable
    public Callable<String> writeContentCallable(String ip, List<String> list){
        return ()->{

            //第一条记录的时间
            int s1 = (ip + " - - [").length();
            int e1 = list.get(0).indexOf("]");
            String content1 = list.get(0).substring(s1,e1);

            //最后一条记录的时间
            int s2 = (ip + " - - [").length();
            int e2 = list.get(list.size()-1).indexOf("]");
            String content2 = list.get(list.size()-1).substring(s2,e2);

            String result = ip +"-------------->"+ content1 +" - "+ content2;

            return result;
        };
    }

    //处理map的callable，根据IP收集相同IP的list，并组装成map
    public Callable<Map<String,List<String>>> handleMapCallable(String ip, List<String> contentList){
        return ()->{
            Map<String,List<String>> map = new HashMap<>();

            List<String> ipContentList = new ArrayList<>();
            for (String c : contentList) {
                if(c.contains(ip)){
                    ipContentList.add(c);
                }
            }
            map.put(ip, ipContentList);
            System.out.println(Thread.currentThread().getName());

            return map;
        };
    }
}
